#include "syscore.h"
#include "apis.h"
#include "common.h"
#include <unistd.h>
#include "modules.h"
#include <signal.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <dirent.h>

volatile BOOL sigInt = FALSE;


void SYS_IntHandler( int arg)
{
    unlink("flag");
#if 1    
    dbgprintf(DEBUG_EMERG, stderr, "modId[0x%x] system is exiting, closing socket. \n", MODULE_SYSTEM);
    CM_SendMsg_noPara(MODULE_GSM_CAP, MODULE_SYSTEM,MSG_TYPE_COMMAND,CMD_EVENT,CMD_CODE_SYS_EXIT,0);
    CM_SendMsg_noPara(MODULE_TDSCDMA_CAP, MODULE_SYSTEM,MSG_TYPE_COMMAND,CMD_EVENT,CMD_CODE_SYS_EXIT,0);
    CM_SendMsg_noPara(MODULE_WCDMA_CAP, MODULE_SYSTEM,MSG_TYPE_COMMAND,CMD_EVENT,CMD_CODE_SYS_EXIT,0);
    CM_SendMsg_noPara(MODULE_WIFI, MODULE_SYSTEM,MSG_TYPE_COMMAND,CMD_EVENT,CMD_CODE_SYS_EXIT,0);
    CM_SendMsg_noPara(MODULE_EUTRAN_SNIFFER, MODULE_SYSTEM,MSG_TYPE_COMMAND,CMD_EVENT,CMD_CODE_SYS_EXIT,0);
    
    //do some unInit thing here
    dbgprintf(DEBUG_EMERG, stderr, "modId[0x%x] system exited, socket closed. \n", MODULE_SYSTEM);

#endif

    sleep(5);
    sigInt = TRUE;
}

/*

main 

*/
//have output
#define DAMON_MODE_1 1
//have not output
#define DAMON_MODE_2 2

#define BUF_SIZE 1024

pid_t getPidByName(char* task_name)
{
    DIR *dir;
    struct dirent *ptr;
    FILE *fp;
    char filepath[50];
    char cur_task_name[50];
    char buf[BUF_SIZE];
    
    dir = opendir("/proc");
    pid_t pid = 0;
    
    if (NULL != dir)
    {
        while ((ptr = readdir(dir)) != NULL)
        {
            if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0))
            continue;

            if (DT_DIR != ptr->d_type)
            continue;

            sprintf(filepath, "/proc/%s/status", ptr->d_name);
            fp = fopen(filepath, "r");
            if (NULL != fp)
            {
                if( fgets(buf, BUF_SIZE-1, fp)== NULL )
                {
                    fclose(fp);
                    continue;
                }

                sscanf(buf, "%*s %s", cur_task_name);

                if (!strcmp(task_name, cur_task_name))
                {
                    pid_t tmp;
                    tmp = atoi(ptr->d_name);
                    if(tmp != getpid())
                    {
                        pid = tmp;
                        //discard current pid                    
                        fclose(fp);
                        break;
                    }
                }
                fclose(fp);
            }

        }
        closedir(dir);
    }
    return pid;
}



int main(int argc,char **argv)
{
    int opt;
    char opts[]="dl:";
    int mode = 0;
    int level = DEBUG_NOTICE;
    sigset_t set;
    struct sigaction sa;
    pid_t opid = 0;

    if((opid = getPidByName("bes")))
    {
        printf("Another instance %d is running, Exit\n", opid);
        return RC_FAIL;
    }
    
    prctl(PR_SET_NAME, "bes");
	
    while((opt = getopt(argc,argv,opts)) != -1)
    {
        switch(opt)
        {
            case 'd':
                mode = atoi(optarg);
                if ((mode == 0) || (mode > DAMON_MODE_2))
                {
                    printf(" damon mode required\n");
                }
                break;
            case 'l':
                level = atoi(optarg);
                break;
            default:
                break;
        }
    }

    if(mode == DAMON_MODE_1)
    {
        daemon(1,1);
    }
    else if(mode == DAMON_MODE_2)
    {
        daemon(1,0);
    }
    
    sigfillset(&set);
    sigdelset(&set, SIGINT);
    sigdelset(&set, SIGTERM);
    sigdelset(&set, SIGSEGV);
    sigdelset(&set, SIGUSR2);
    sigdelset(&set, SIGILL);
    pthread_sigmask(SIG_SETMASK, &set, NULL);
    
    memset(&sa, 0, sizeof(struct sigaction));
    sigemptyset(&sa.sa_mask);
    sa.sa_handler = SYS_IntHandler;
    sa.sa_flags = 0;
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
    saveImportantLog("system start");
    if(SYS_init() != RC_OK)
        return RC_FAIL;
    
    if(MSGPROC_init() != RC_OK)
        return RC_FAIL;

    if(LogServer_init("BES", "/mnt/usr/log/bes.log", 1) != RC_OK)
        return RC_FAIL;
    //to wait logserver start complete.
    sleep(2);

    if(pwrtask_init() != RC_OK)
        return RC_FAIL;

    if(SYSM_init() != RC_OK)
        return RC_FAIL;

    if(DATAPROC_init() != RC_OK)
        return RC_FAIL;

    if(DATASTOR_init() != RC_OK)
        return RC_FAIL;

//    if(dongle_init() != RC_OK)
//        return RC_FAIL;

    if(patask_init() != RC_OK)
        return RC_FAIL;

    if(GPS_init() != RC_OK)
        return RC_FAIL;

    if(GSM_init() != RC_OK)
       return RC_FAIL;

    if( EUTRAN_init()!=RC_OK )
    {
        return RC_FAIL;
    }

    if (CDMA_init() != RC_OK)
        return RC_FAIL;

    if (WCDMA_init() != RC_OK)
        return RC_FAIL;

    if (TDSCDMA_init() != RC_OK)
        return RC_FAIL;

    if (WIFI_init() != RC_OK)
        return RC_FAIL;

    if ( Monitor_init() != RC_OK )
       return RC_FAIL;

    if ( SCANNER_init() != RC_OK )
       return RC_FAIL;

    if ( WIFIBOARD_init() != RC_OK )
        return RC_FAIL;

    if ( GPSBOARD_init() != RC_OK )
        return RC_FAIL;


	if (level >= DEBUG_EMERG || level <= DEBUG_MAX_LEVEL)
    {
		CSetLogLevel(level);
        SYS_setDebugLevel(level);
    }

    for(;;)
    {
        pause();
        if(sigInt == TRUE)
        {
            //wait other thread to close socket.
            sleep(5);
            break;
        }
    }
   
    return 0;
}
